using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityWebSocket;

public class uSherpaWebGL : MonoBehaviour
{
    IWebSocket ws;
    public InputField prefabIf;
    public InputField nowIf = null;
    Queue<string> msgs = new Queue<string>();

    // Start is called before the first frame update
    void Start()
    {
        prefabIf.gameObject.SetActive(false);
        ws = new WebSocket("wss://usherpa.xuefei.net.cn:9999");
        ws.OnOpen += OnOpen;
        ws.OnMessage += OnMessage;
        ws.OnError += OnError;
        ws.OnClose += OnClose;
        ws.ConnectAsync();
    }

    TextMsg textMsg;
    string msg;
    // Update is called once per frame
    void Update()
    {
        if (msgs.Count > 0)
        {
            if (nowIf == null)
            {
                nowIf = Instantiate(prefabIf, prefabIf.transform.parent);
                nowIf.gameObject.SetActive(true);
            }
            msg = msgs.Dequeue();
            textMsg = JsonUtility.FromJson<TextMsg>(msg);
            if (textMsg.isEndpoint)
            {
                nowIf.text = textMsg.message;
                LayoutRebuilder.ForceRebuildLayoutImmediate(nowIf.GetComponent<RectTransform>());
                nowIf = null;
            }
            else
            {
                nowIf.text += textMsg.message;
            }
        }
    }

    byte[] desArray;
    public void OnData(float[] input)
    {
        //Debug.Log("input.Length:" + input.Length);
        SendData(input);
    }

    int desArraySize;
    IntPtr srcArrayPtr;

    void SendData(float[] input)
    {
        desArraySize = Buffer.ByteLength(input);
        srcArrayPtr = Marshal.UnsafeAddrOfPinnedArrayElement(input, 0);
        desArray = new byte[desArraySize];
        Marshal.Copy(srcArrayPtr, desArray, 0, desArraySize);
        if (ws != null && ws.ReadyState == WebSocketState.Open)
        {
            ws.SendAsync(desArray);
        }
    }

    void OnOpen(object sender, OpenEventArgs e)
    {
        Debug.Log("WS connected!");
    }

    void OnMessage(object sender, MessageEventArgs e)
    {
        if (e.IsBinary)
        {
            string str = Encoding.UTF8.GetString(e.RawData);
            Debug.Log("WS received message: " + str);
            msgs.Enqueue(str);
        }
        else if (e.IsText)
        {

        }
    }

    void OnError(object sender, ErrorEventArgs e)
    {
        Debug.Log("WS error: " + e.Message);
    }

    void OnClose(object sender, CloseEventArgs e)
    {
        Debug.Log(string.Format("Closed: StatusCode: {0}, Reason: {1}", e.StatusCode, e.Reason));
    }

    private void OnApplicationQuit()
    {
        if (ws != null && ws.ReadyState != WebSocketState.Closed)
        {
            ws.CloseAsync();
        }
    }
}